package client;

import network.client.ChatException;
import network.client.ClientApplication;
import network.server.Server;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.*;
import java.util.Arrays;
import java.util.Collection;

import static org.junit.Assert.*;

@RunWith(Parameterized.class)
public class ClientTestPositive {
    private static final PrintStream defaultSystemOut = System.out;
    private static final String scenariosFolder = ".\\src\\test\\java\\client\\scenarios\\";

    private static BufferedReader kbdReader;
    private static BufferedReader screenReader;

    private ClientApplication clientApplication;

    private String kbdInput;
    private String screenOutput;

    public ClientTestPositive(String fileName) {
        try {
            System.out.println("Running test scenario from " + fileName);
            kbdReader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Before
    public void setUp() {
        clientApplication = new ClientApplication();
        clientApplication.start("localhost", 888);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            return;
        }

        try {
            File f = new File("src\\test\\java\\client\\screenOutput.txt");
            f.delete();
            f.createNewFile();
            System.setOut(new PrintStream("src\\test\\java\\client\\screenOutput.txt"));
            screenReader = new BufferedReader(new FileReader("src\\test\\java\\client\\screenOutput.txt"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void positiveTest() {
        try {
            while ((kbdInput = kbdReader.readLine()) != null) {
                clientApplication.getStub().processClientRequest(kbdInput);
                Thread.sleep(100);
                screenOutput = screenReader.readLine();
                kbdInput = kbdReader.readLine();
                if (screenOutput != null) {
                    assertTrue(screenOutput.matches(kbdInput));
                }
            }
        } catch (ChatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @After
    public void tearDown() {
        System.setOut(defaultSystemOut);
        try {
            clientApplication.close();
            screenReader.close();
            kbdReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Parameterized.Parameters
    public static Collection testFiles() {
        File folder = new File(scenariosFolder);
        String[] files = folder.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.matches(".*\\.txt");
            }
        });
        String[][] array = new String[files.length][1];
        for (int i = 0; i < files.length; i++) {
            array[i][0] = scenariosFolder + files[i];
        }
        System.out.println(array[0][0]);
        return Arrays.asList(array);
    }
}
